package com.sunda.spmsweb.wmscontroller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmsweb.util.JWTUtil;
import com.sunda.spmswms.service.ISapDeliveryNoteLogService;
import com.sunda.spmswms.service.ISapPackageListService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * <p>
 * SAP装箱单表抬头 前端控制器
 * </p>
 *
 * @author Wayne
 * @since 2021-04-22
 */
@RestController
@RequestMapping("/sapPackageList")
@Api(tags = "装箱单/出库任务初始化", description = "装箱单/出库任务初始化")
public class SapPackageListController {

    @Autowired
    ISapPackageListService iSapPackageListService;

    @Autowired
    ISapDeliveryNoteLogService iSapDeliveryNoteLogService;

    @PostMapping("/getSapPackageList")
    @ApiOperation(value = "获取装箱单任务Page分页",notes = "获取装箱单任务\n" +
            "1.装箱单号为空时，默认查询所有跟用户相关的装箱单号，返回信息到前端；\n" +
            "2.装箱单号不为空时：\n" +
            "    2.1 首先在 SPMS 查询该装箱单数据，存在则返回该数据到前端；\n" +
            "    2.2 不存在时则实时向 SAP REST 请求一次箱单数据：\n" +
            "           SAP 返回错误则将错误信息返回给前端展示；\n" +
            "           SAP 实时返回装箱单信息，则将装箱单信息写入 SPMS 数据库。再执行一次查询返回信息到前端。")
    public ResponseResult getSapPackageList(String packageList, String spmsStatus, @RequestParam int pageNo, @RequestParam int pageSize){
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        try {
            Page<Map<String, Object>> pageData = iSapPackageListService.getSapPackageListPage(userId, packageList, spmsStatus, pageNo, pageSize);
            return ResponseResult.success().add("sapPackageList", pageData);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("获取装箱单信息出错");
        }
    }

    @PostMapping("/getSapPackageListDtl")
    @ApiOperation(value = "获取装箱单任务明细",notes = "获取装箱单任务明细以及装箱单操作日志信息，备件包含箱码信息。" +
            "packageList=PL1001")
    public ResponseResult getSapPackageListDtl(String packageList){
        try {
            return ResponseResult.success()
                    .add("sapPackageListDtl", iSapPackageListService.getSapPackageListDtl(packageList))
                    .add("sapPackageListLog", iSapDeliveryNoteLogService.getDocumentLogs(packageList));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("获取装箱单信息出错");
        }
    }

    @PostMapping("/updateSapPackageList")
    @ApiOperation(value = "更新装箱单同时生成出库任务",notes = "更新装箱单同时生成出库任务\n" +
            "packageList 装箱单号；targetStatus 更新后状态；currentStatus 当前状态；三个参数都必输；\n" +
            "20210714——检查装箱单信息数据是否为能被拆分执行的正确数据，若为脏数据则返回错误信息;\n" +
            "I 上游数据是否准确判别逻辑如下：\n" +
            "1.装箱单没有明细行（目前没发生），系统提示错误；\n" +
            "2.装箱单明细 货物类型 字段为‘M’和‘X’以外的值 SAP_PACKAGE_LIST_DTL，系统提示错误（目前没发生）；\n" +
            "3.装箱单备件明细行，没有装箱明细箱码关系数据 SAP_PACKAGE_BOX，系统提示错误；\n" +
            "4.装箱单备件明细行，有装箱单明细箱码关系的情况下，再判断明细中的箱码在 箱码信息表 是否存在，不存在则系统提示错误（目前没发生）；\n" +
            "5.装箱单贸易货明细行，如果存在装箱单明细箱码关系 SAP_PACKAGE_BOX，系统提示错误；\n\n" +
            "II 装箱单更新拆分出库任务逻辑如下：\n" +
            "1.更新装箱单表头。更新前该装箱单状态必须为 0待处理，否则不让更新；\n" +
            "2.更新装箱单表表头状态为目标状态；\n" +
            "3.实时向SAP发出 REST 请求信息，告知该装箱单已开始处理请锁定不再更新；\n" +
            "4.更新装箱单明细表对应的行状态；\n" +
            "5.装箱单更新成功后，执行 generateWhsOutTask 方法，按 装柜地点、货物类型、柜序号、可装柜日期 四个维度拆分出库任务；\n" +
            "6.装箱单明细逐行遍历转换成出库任务：如果出库任务已经存在，则将该出库任务的 任务uuid 写入 装箱单明细对应行；" +
            "如果出库任务不存在，则新建一个出库任务，同时将 出库任务uuid 写入 装箱单明细对应行；\n" +
            "7.记录装箱单操作日志；\n" +
            "8.记录出库任务日志；")
    public ResponseResult updateSapPackageList(String packageList, String targetStatus, String currentStatus){
        String userId = JWTUtil.getUserId(SecurityUtils.getSubject().getPrincipal().toString());
        /** 检查装箱单信息数据是否为能被拆分执行的正确数据，若为脏数据则返回错误信息 */
        ResponseResult checkResult = iSapPackageListService.checkSapPackageListCanBeSplit(packageList);
        if (checkResult.getCode() != 200){
            return checkResult;
        }
        try {
            int resp = iSapPackageListService.updateSapPackageList(userId, packageList, targetStatus, currentStatus);
            if (resp > 0){
                return ResponseResult.success().add("sapPackageList", iSapPackageListService.getSapPackageList(userId, packageList, null));
            }else {
                return ResponseResult.error("更新装箱单信息出错");
            }
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("更新装箱单信息出错");
        }
    }

    @PostMapping("/getSapPackageListDtlM")
    @ApiOperation(value = "获取装箱单实际结果详情-贸易货",notes = "贸易货卸货入库，根据装箱单号查询装箱单结果详情数据" +
            "packageList=PL00027371, 或 PL00027372")
    public ResponseResult getSapPackageListDtlM(String packageList){
        try {
            return ResponseResult.success().add("sapPackageListDtlM", iSapPackageListService.getSapPackageListDtlM(packageList));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("获取装箱单详细信息出错");
        }
    }

    @PostMapping("/lockSapPackageList")
    @ApiOperation(value = "装箱单执行通知SAP上锁",notes = "装箱单执行通知SAP上锁" +
            "packageList=PL00027371, 或 PL00027372")
    public ResponseResult lockSapPackageList(String packageList){
        try {
            JSONObject doc = iSapPackageListService.lockSapPackageList(packageList);
            return ResponseResult.success()
                    .add("dataToSap", doc.getJSONObject("dataToSap"))
                    .add("sapReturnedData", doc.getJSONObject("sapReturnedData"));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("装箱单上锁出错");
        }
    }


    @PostMapping("/getSapPackageListRest")
    @ApiOperation(value = "从SAP实时Rest请求箱单数据",notes = "从SAP实时Rest请求箱单数据\n" +
            "packageList=PL00027371, 或 PL00027372，PL00038154，仅展示给前端用户查看，不做数据库更新或存储。")
    public ResponseResult getSapPackageListRest(String packageList){
        try {
            return iSapPackageListService.getSapPackageListRest(packageList);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage());
        }
    }

    @PostMapping("/checkSapPackageListCanBeSplit")
    @ApiOperation(value = "判断装箱单数据能否被拆分",notes = "判断装箱单数据能否被拆分\n" +
            "判断装箱单数据能否被拆分。\n" +
            "M SP00000100; X SP00000300; M+X SP00000450;")
    public ResponseResult checkSapPackageListCanBeSplit(String packageList){
        try {
            return iSapPackageListService.checkSapPackageListCanBeSplit(packageList);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage());
        }
    }

}
